//  @ Project : GagalPanen
//  @ File Name : movingcreature.cpp
//  @ Date : 3/9/2011
//  @ Author : Denis, Irvan
//
//

#include <assert.h>

#include "movingcreature.hpp"
#include "direction.hpp"
#include "game.hpp"
#include "cell.hpp"

MovingCreature::MovingCreature(GameInterface* game, Cell* cell) :
    Creature(game, cell), direction_(kUp) {
}

MovingCreature::MovingCreature(GameInterface* game, std::ifstream& is) :
    Creature(game, is), direction_(kUp) {
  int direction_id;
  is >> direction_id;
  direction_ = Direction(direction_id);
}

void MovingCreature::save(std::ofstream& os) {
  Creature::save(os);
  os << (int)getDirection() << std::endl;
}

MovingCreature::~MovingCreature() {
}

bool MovingCreature::canMove() {
  Cell* cell_in_front =
          game_->getMaps()->getCellInFrontOff(getCell(), getDirection());
  return cell_in_front->isSteppable();
}

Direction MovingCreature::getDirection() {
  return direction_;
}

void MovingCreature::move() {
  assert(canMove());
  Cell* cell_in_front =
          game_->getMaps()->getCellInFrontOff(getCell(), getDirection());
  cell_ = cell_in_front;
}

void MovingCreature::setDirection(Direction dir) {
  direction_ = dir;
}

void MovingCreature::turnLeft() {
  direction_ = DirectionNamespace::getTurnLeft(getDirection());
  return;
}

void MovingCreature::turnRight() {
  direction_ = DirectionNamespace::getTurnRight(getDirection());
  return;
}

void MovingCreature::setLocation(Cell* new_location) {
  cell_ = new_location;
  return;
}

void MovingCreature::performAction(ActionType action) {
  Cell* front_of_cell = game_->getMaps()->getCellInFrontOff(
          getCell(), getDirection());
  Fruit* result;
  PlantableCell* pc;
  switch (action) {
    case kActionStay :
      break;
    case kActionLeft :
      turnLeft();
      break;
    case kActionDown :
      turnLeft();
      turnLeft();
      break;
    case kActionRight :
      turnRight();
      break;
    case kActionUp :
      move();
      break;
    case kActionHarvestAndSell :
      result = game_->getCreatures()->getPlants()->getPlantAt(front_of_cell)->harvest();
      game_->getInventory()->modifyMoney(result->getPrice());
      break;
    case kActionSickle :
      pc = (PlantableCell*) front_of_cell;
      game_->getCreatures()->getPlants()->removePlant(
              game_->getCreatures()->getPlants()->getPlantAt(pc));
      break;
    case kActionWater :
      pc = (PlantableCell*) front_of_cell;
      pc->water();
      break;
    case kActionPlow :
      pc = (PlantableCell*) front_of_cell;
      pc->plow();
      break;
  }
}
